import express, { Express, Request, Response, NextFunction } from 'express';
import mongoose from 'mongoose';
import HttpException from './exceptions/HttpException';
import cors from 'cors'; // cors是跨域的中间件，
import morgan from 'morgan'; //morgan是打印日志的，
import helmet from 'helmet'; //helmet是可以让express增加点安全性的中间件。
import errorMiddleware from './middlewares/errorMiddleware';
import * as userController from './controller/user';
import * as sliderController from './controller/slider';
import * as lessonController from './controller/lesson';
import dotenv from 'dotenv'
import multer from 'multer';
import path from 'path';
import { Slider, Lesson } from './models';
// https://blog.csdn.net/yehuozhili/article/details/104306072
dotenv.config()
// require('dotenv').config() // 默认读取项目根目录下的.env文件
// https://blog.csdn.net/yehuozhili/article/details/104306072
//https://blog.csdn.net/yehuozhili/article/details/104306072

// 新建文件.env。里面配置密钥数据库地址之类：
// 使用dotenv/config，可以把这个文件的东西写入env里去。
// 例如通过process.env.JWT_SECRET_KEY拿到值。

// 虽然给出了一个自定义存储的方式，让开发者设定存储路径和命名：
// 这里有两点值得留意：

// 1是destination和filename函数的参数req，在这里req.body是空对象{}，
// 未装载formdata的文本域数据。
const storage = multer.diskStorage({
  destination: path.join(__dirname, "public", "uploads"), //目录上传文件目录
  filename(_req: Request, file: Express.Multer.File, cb) {
    cb(null, Date.now()+path.extname(file.originalname));//文件名字
  },
});
const upload = multer({ storage });
const app: Express = express();
app.use(morgan("dev"));
app.use(cors());
app.use(helmet());
app.use(express.static(path.resolve(__dirname, "public")));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.get("/", (_req: Request, res: Response) => {
  res.json({
    success: true,
    message: 'hello word'
  })
});
// 模型写完需要用起来，下面做个路由来注册：
app.get("/user/validate", userController.validate);
app.post("/user/register", userController.register);
app.post("/user/login", userController.login);
app.post(
  "/user/uploadAvatar",
  upload.single("avatar"),
  userController.uploadAvatar
);

app.get("/slider/list", sliderController.list);
app.get("/lesson/list", lessonController.list);
app.get("/lesson/:id", lessonController.get);
// 错误中间件需要这的next传错误给中间件一个参数。
// 不传参数则错误中间件收不到err，所以这里负责提供状态码和信息。
// 将中间件按顺序排，走完所有路由后未匹配到的就给404，传错误信息给错误中间件。
app.use((_req: Request, _res: Response, next: NextFunction) => {
  // 用类来做类型，后面还需要把状态码和信息传给它(HttpException)然后new它。
  // 然后把错误信息传给错误中间件errorMiddleware
  const error: HttpException = new HttpException(404, "Route not found=>未分配路由");
  next(error);
});
// 将中间件按顺序排，走完所有路由后未匹配到的就给404，传错误信息给错误中间件。
app.use(errorMiddleware);

const PORT: number = (process.env.PORT && parseInt(process.env.PORT)) || 8000;


// mongodb 启动的时候指定端口和访问服务器的路径。
(async function () {
  mongoose.set("useNewUrlParser", true);
  mongoose.set("useUnifiedTopology", true);
  console.log(process.env, 'process.env');
  console.log(process.env.MONGODB_URL, 'MONGODB_URL');
  console.log(process.env.PORT, 'PORT');


  // mongodb://localhost:27017/zhufengketang
  const MONGODB_URL = process.env.MONGODB_URL! || 'mongodb://localhost/zhufengketang'
  await mongoose.connect(MONGODB_URL);
  await createSliders();
  await createLessons();
  // await mongoose.connect("mongodb://localhost/zhufengketang");
  app.listen(PORT, () => {
    console.log(`Running on http://localhost:${PORT}`);
  })
})();



async function createSliders() {
  const sliders = await Slider.find();
  console.log(sliders, 'sliders=>插入轮播数据给数据库')
  if (sliders.length == 0) {
    const sliders: any = [
      { url: 'http://img.zhufengpeixun.cn/post_reactnative.png' },
      { url: 'http://img.zhufengpeixun.cn/post_react.png' },
      { url: 'http://img.zhufengpeixun.cn/post_vue.png' },
      { url: 'http://img.zhufengpeixun.cn/post_wechat.png' },
      { url: 'http://img.zhufengpeixun.cn/post_architect.jpg' }
    ];
    Slider.create(sliders);
  }
}


async function createLessons() {
  const lessons = await Lesson.find();
  console.log(lessons, 'lessons=>插入课程数据给数据库')
  if (lessons.length == 0) {
    const lessons: any = [
      {
        order: 1,
        title: "1.React全栈架构",
        video: "http://img.zhufengpeixun.cn/gee2.mp4",
        poster: "http://img.zhufengpeixun.cn/react_poster.jpg",
        url: "http://img.zhufengpeixun.cn/react_url.png",
        price: "¥100.00元",
        category: "react",
      },
      {
        order: 2,
        title: "2.React全栈架构",
        video: "http://img.zhufengpeixun.cn/gee2.mp4",
        poster: "http://img.zhufengpeixun.cn/react_poster.jpg",
        url: "http://img.zhufengpeixun.cn/react_url.png",
        price: "¥200.00元",
        category: "react",
      },
      {
        order: 3,
        title: "3.React全栈架构",
        video: "http://img.zhufengpeixun.cn/gee2.mp4",
        poster: "http://img.zhufengpeixun.cn/react_poster.jpg",
        url: "http://img.zhufengpeixun.cn/react_url.png",
        price: "¥300.00元",
        category: "react",
      },
      {
        order: 4,
        title: "4.React全栈架构",
        video: "http://img.zhufengpeixun.cn/gee2.mp4",
        poster: "http://img.zhufengpeixun.cn/react_poster.jpg",
        url: "http://img.zhufengpeixun.cn/react_url.png",
        price: "¥400.00元",
        category: "react",
      },
      {
        order: 5,
        title: "5.React全栈架构",
        video: "http://img.zhufengpeixun.cn/gee2.mp4",
        poster: "http://img.zhufengpeixun.cn/react_poster.jpg",
        url: "http://img.zhufengpeixun.cn/react_url.png",
        price: "¥500.00元",
        category: "react",
      },
      {
        order: 6,
        title: "6.Vue从入门到项目实战",
        video: "http://img.zhufengpeixun.cn/gee2.mp4",
        poster: "http://img.zhufengpeixun.cn/vue_poster.png",
        url: "http://img.zhufengpeixun.cn/vue_url.png",
        price: "¥100.00元",
        category: "vue",
      },
      {
        order: 7,
        title: "7.Vue从入门到项目实战",
        video: "http://img.zhufengpeixun.cn/gee2.mp4",
        poster: "http://img.zhufengpeixun.cn/vue_poster.png",
        url: "http://img.zhufengpeixun.cn/vue_url.png",
        price: "¥200.00元",
        category: "vue",
      },
      {
        order: 8,
        title: "8.Vue从入门到项目实战",
        video: "http://img.zhufengpeixun.cn/gee2.mp4",
        poster: "http://img.zhufengpeixun.cn/vue_poster.png",
        url: "http://img.zhufengpeixun.cn/vue_url.png",
        price: "¥300.00元",
        category: "vue",
      },
      {
        order: 9,
        title: "9.Vue从入门到项目实战",
        video: "http://img.zhufengpeixun.cn/gee2.mp4",
        poster: "http://img.zhufengpeixun.cn/vue_poster.png",
        url: "http://img.zhufengpeixun.cn/vue_url.png",
        price: "¥400.00元",
        category: "vue",
      },
      {
        order: 10,
        title: "10.Vue从入门到项目实战",
        video: "http://img.zhufengpeixun.cn/gee2.mp4",
        poster: "http://img.zhufengpeixun.cn/vue_poster.png",
        url: "http://img.zhufengpeixun.cn/vue_url.png",
        price: "¥500.00元",
        category: "vue",
      },
      {
        order: 11,
        title: "11.React全栈架构",
        video: "http://img.zhufengpeixun.cn/gee2.mp4",
        poster: "http://img.zhufengpeixun.cn/react_poster.jpg",
        url: "http://img.zhufengpeixun.cn/react_url.png",
        price: "¥600.00元",
        category: "react",
      },
      {
        order: 12,
        title: "12.React全栈架构",
        video: "http://img.zhufengpeixun.cn/gee2.mp4",
        poster: "http://img.zhufengpeixun.cn/react_poster.jpg",
        url: "http://img.zhufengpeixun.cn/react_url.png",
        price: "¥700.00元",
        category: "react",
      },
      {
        order: 13,
        title: "13.React全栈架构",
        video: "http://img.zhufengpeixun.cn/gee2.mp4",
        poster: "http://img.zhufengpeixun.cn/react_poster.jpg",
        url: "http://img.zhufengpeixun.cn/react_url.png",
        price: "¥800.00元",
        category: "react",
      },
      {
        order: 14,
        title: "14.React全栈架构",
        video: "http://img.zhufengpeixun.cn/gee2.mp4",
        poster: "http://img.zhufengpeixun.cn/react_poster.jpg",
        url: "http://img.zhufengpeixun.cn/react_url.png",
        price: "¥900.00元",
        category: "react",
      },
      {
        order: 15,
        title: "15.React全栈架构",
        video: "http://img.zhufengpeixun.cn/gee2.mp4",
        poster: "http://img.zhufengpeixun.cn/react_poster.jpg",
        url: "http://img.zhufengpeixun.cn/react_url.png",
        price: "¥1000.00元",
        category: "react",
      },
      {
        order: 16,
        title: "16.Vue从入门到项目实战",
        video: "http://img.zhufengpeixun.cn/gee2.mp4",
        poster: "http://img.zhufengpeixun.cn/vue_poster.png",
        url: "http://img.zhufengpeixun.cn/vue_url.png",
        price: "¥600.00元",
        category: "vue",
      },
      {
        order: 17,
        title: "17.Vue从入门到项目实战",
        video: "http://img.zhufengpeixun.cn/gee2.mp4",
        poster: "http://img.zhufengpeixun.cn/vue_poster.png",
        url: "http://img.zhufengpeixun.cn/vue_url.png",
        price: "¥700.00元",
        category: "vue",
      },
      {
        order: 18,
        title: "18.Vue从入门到项目实战",
        video: "http://img.zhufengpeixun.cn/gee2.mp4",
        poster: "http://img.zhufengpeixun.cn/vue_poster.png",
        url: "http://img.zhufengpeixun.cn/vue_url.png",
        price: "¥800.00元",
        category: "vue",
      },
      {
        order: 19,
        title: "19.Vue从入门到项目实战",
        video: "http://img.zhufengpeixun.cn/gee2.mp4",
        poster: "http://img.zhufengpeixun.cn/vue_poster.png",
        url: "http://img.zhufengpeixun.cn/vue_url.png",
        price: "¥900.00元",
        category: "vue",
      },
      {
        order: 20,
        title: "20.Vue从入门到项目实战",
        video: "http://img.zhufengpeixun.cn/gee2.mp4",
        poster: "http://img.zhufengpeixun.cn/vue_poster.png",
        url: "http://img.zhufengpeixun.cn/vue_url.png",
        price: "¥1000.00元",
        category: "vue",
      }
    ];
    Lesson.create(lessons);
  }
}